package com.micro.ai.auth.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.micro.ai.auth.entity.DictType;
import com.micro.ai.auth.entity.DictData;
import com.micro.ai.auth.mapper.DictTypeMapper;
import com.micro.ai.auth.service.DictTypeService;
import com.micro.ai.auth.service.DictDataService;
import com.micro.ai.commons.exception.BusinessException;
import com.micro.ai.commons.util.IdUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 字典类型服务实现类
 *
 * @author micro-ai
 * @since 2025-01-29
 */
@Slf4j
@Service
public class DictTypeServiceImpl extends ServiceImpl<DictTypeMapper, DictType> implements DictTypeService {

    @Autowired
    @Lazy
    private DictDataService dictDataService;

    @Override
    public IPage<DictType> getDictTypePage(Page<DictType> page, String code, String name, String status, String tenantId) {
        return baseMapper.selectDictTypePage(page, code, name, status, tenantId);
    }

    @Override
    public DictType getByCode(String code, String tenantId) {
        return baseMapper.selectByCode(code, tenantId);
    }

    @Override
    public List<DictType> getActiveDictTypes(String tenantId) {
        return baseMapper.selectActiveDictTypes(tenantId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean createDictType(DictType dictType) {
        // 检查编码是否已存在
        if (existsByCode(dictType.getCode(), dictType.getTenantId(), null)) {
            throw new BusinessException("字典类型编码已存在");
        }

        // 设置ID和创建时间
        dictType.setId(IdUtils.generateId());
        dictType.setCreatedAt(LocalDateTime.now());
        dictType.setUpdatedAt(LocalDateTime.now());

        return save(dictType);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateDictType(DictType dictType) {
        // 检查编码是否已存在（排除自己）
        if (existsByCode(dictType.getCode(), dictType.getTenantId(), dictType.getId())) {
            throw new BusinessException("字典类型编码已存在");
        }

        // 设置更新时间
        dictType.setUpdatedAt(LocalDateTime.now());

        return updateById(dictType);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteDictType(String id) {
        // 检查字典类型是否存在（直接使用SQL查询，不应用逻辑删除过滤）
        DictType dictType = baseMapper.selectByIdIgnoreLogic(id);
        if (dictType == null || dictType.getDeletedAt() != null) {
            throw new BusinessException("字典类型不存在或已被删除");
        }

        // 1. 级联删除关联的字典数据
        List<DictData> dictDataList = dictDataService.getByDictTypeId(id);
        if (dictDataList != null && !dictDataList.isEmpty()) {
            List<String> dictDataIds = dictDataList.stream()
                    .map(DictData::getId)
                    .collect(Collectors.toList());
            log.info("删除字典类型，级联删除 {} 条字典数据: dictTypeId={}", dictDataIds.size(), id);
            dictDataService.batchDeleteDictData(dictDataIds);
        }

        // 2. 物理删除字典类型（使用直接SQL删除，绕过逻辑删除）
        int deleteResult = baseMapper.deleteByIdPhysical(id);
        log.info("物理删除字典类型: id={}, result={}", id, deleteResult > 0);
        
        if (deleteResult == 0) {
            throw new BusinessException("删除字典类型失败");
        }
        
        return deleteResult > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchDeleteDictTypes(List<String> ids) {
        if (ids == null || ids.isEmpty()) {
            return true;
        }

        // 批量级联删除：先删除关联的字典数据
        for (String id : ids) {
            // 检查是否存在（直接使用SQL查询，不应用逻辑删除过滤）
            DictType dictType = baseMapper.selectByIdIgnoreLogic(id);
            if (dictType != null && dictType.getDeletedAt() == null) {
                // 级联删除关联的字典数据
                List<DictData> dictDataList = dictDataService.getByDictTypeId(id);
                if (dictDataList != null && !dictDataList.isEmpty()) {
                    List<String> dictDataIds = dictDataList.stream()
                            .map(DictData::getId)
                            .collect(Collectors.toList());
                    log.info("批量删除字典类型，级联删除字典数据: dictTypeId={}, count={}", id, dictDataIds.size());
                    dictDataService.batchDeleteDictData(dictDataIds);
                }
            }
        }

        // 批量物理删除字典类型（使用直接SQL删除，绕过逻辑删除）
        int totalDeleteCount = 0;
        for (String id : ids) {
            int deleteResult = baseMapper.deleteByIdPhysical(id);
            if (deleteResult > 0) {
                totalDeleteCount++;
            }
        }
        log.info("批量物理删除字典类型: count={}, result={}", ids.size(), totalDeleteCount);
        
        return totalDeleteCount > 0;
    }

    @Override
    public boolean existsByCode(String code, String tenantId, String excludeId) {
        LambdaQueryWrapper<DictType> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DictType::getCode, code);
        if (tenantId != null) {
            wrapper.eq(DictType::getTenantId, tenantId);
        } else {
            wrapper.isNull(DictType::getTenantId);
        }
        wrapper.ne(excludeId != null, DictType::getId, excludeId);
        wrapper.isNull(DictType::getDeletedAt);

        return count(wrapper) > 0;
    }
}
